<?php

/**
 * 商标管理系统 v1.0.1
 *
 * 商业运营到ubtm.cn官网进行授权使用。
 *
 * (c) cighsen02 <xiayu@959602.com>
 *
 * Create at：2025.07.04
*/

namespace App\Services\Support;

use chillerlan\QRCode\Output\QROutputInterface;
use chillerlan\QRCode\QRCode as ChillerlanQRCode;
use chillerlan\QRCode\QROptions;
use Exception;


/**
 * 二维码显示
 */
class QrCode
{
    const CONTENT_TYPE = [
        ChillerlanQRCode::OUTPUT_IMAGE_PNG => 'image/png',
        ChillerlanQRCode::OUTPUT_IMAGE_GIF => 'image/gif',
        ChillerlanQRCode::OUTPUT_IMAGE_JPG => 'image/jpeg',
    ];

    //类型
    private string $contentType;

    public function __construct(
        private ?array $options = null
    )
    {
        $this->contentType = static::CONTENT_TYPE[ChillerlanQRCode::OUTPUT_IMAGE_PNG];
    }

    /**
     * 生成二维码
     * 
     * @param string $data 生成字符串
     * @param string $contentType png|gif|jpg
     * @param string $file
     * @return string
     * 
     * @throws Exception
     */
    public function image(string $data, string $contentType = 'png', ?string $file = null): string
    {
        $contentType = strtolower($contentType);

        if (array_key_exists($contentType, static::CONTENT_TYPE)) {
            // 更新图片类型
            if (ChillerlanQRCode::OUTPUT_IMAGE_PNG !== $contentType) $this->contentType = static::CONTENT_TYPE[$contentType];
        }
        else {
            throw new Exception('仅支持png、gif、jpg', 422);
        }
        
        // url类型，进行转码
        if ($data && str_starts_with($data, 'http')) $data = rawurldecode($data);
        
        // 配制
        $options = new QROptions([
            'version'      => 6,
            'outputType'   => $contentType,
            // L,M,Q,H容错级别
            'eccLevel'     => ChillerlanQRCode::ECC_Q,
            'addQuietzone' => $this->options['addQuietzone'] ?? true,
            'quietzoneSize'=> $this->options['quietzoneSize'] ?? 2,
            // 'scale'        => 5,
            'outputBase64'  => $this->options['outputBase64'] ?? true,
            'moduleValues' => [
        // 		// finder
        // 		1536 => [0, 63, 255], // dark (true)
        // 		6    => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
        // 		5632 => [241, 28, 163], // finder dot, dark (true)
        // 		// alignment
        // 		2560 => [255, 0, 255],
        //		10   => [255, 255, 255],
        // 		// timing
        // 		3072 => [255, 0, 0],
        // 		12   => [255, 255, 255],
        // 		// format
        // 		3584 => [67, 99, 84],
        // 		14   => [255, 255, 255],
        // 		// version
        // 		4096 => [62, 174, 190],
        // 		16   => [255, 255, 255],
        // 		// data
        // 		1024 => [0, 0, 0],
        // 		4    => [255, 255, 255],
        // 		// darkmodule
        // 		512  => [0, 0, 0],
        // 		// separator
        // 		8    => [255, 255, 255],
        // 		// quietzone
        // 		18   => [255, 255, 255],
        // 		// logo (requires a call to QRMatrix::setLogoSpace())
        // 		20    => [255, 255, 255],
            ]
        ]);
        
        return new ChillerlanQRCode($options)->render($data, $file);
    }

    /**
     * 输出图片类型
     * 
     * @return string
     */
    public function getContentType(): string
    {
        return $this->contentType;
    }
}